home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
program
/
qlib205.zip
/
QLIB.ZIP
/
SRC
/
GRAFIX
/
VESA.ASM
< prev
next >
Wrap
Assembly Source File
|
1997-04-12
|
12KB
|
558 lines
; Simple VESA Driver
; Version 2.00 (from video.asm in QLIB v1.2)
; Supports : VESA 2.0 and 1.2 fully
.data?
bankshift db ?
align 4
PmodeSetStart DD ?
ProgramBaseAddress DD ?
vesamode DW ?
Total64Kblocks DW ?
vesa_current_bank DB ?
VBE_StarPerPixelFactor DB ?
vesa_ver DW ?
vesa_info vesa_infoblock <>
vesa_modeinfo vesa_modeinfoblock <>
.data
vesa_list dd 0 ;list of video modes
vesa_list_pos dd 0 ;current POS when using first/next mode()
align 4
vbesetbank DD Offset SetBank_RealMode
vesa_setstart_proc DD Offset SetStart_RealMode
_800_ DD 0 ;this is the linear addr returned by DPMI func #800h
std_list label word ;VESA standard video mode list
dw 10fh
dw 112h
dw 104h
dw 0ffffh
.code
vesa_uninit proc private
.if _800_
pushad
mov ax,801h
mov bx,wptr cs:[_800_+2]
mov cx,wptr cs:[_800_]
int 31h
mov _800_,0
popad
.endif
mov exitmode,NULLPROC
ret
vesa_uninit endp
vesa_init proc
pushad
mov ax,_8kbufferseg
mov _es_,ax
mov ax,4F00h
xor edi,edi ; (real mode) ES:DI -> 256 byte buffer
int 10h ; GET VESA INFORMATION
;c0.asm always loads DS,ES in RMODE with _es_,_ds_
; when using int 10h
cmp ax,004Fh
jne bad
mov esi,_8kbuffer
mov edi,offset vesa_info
mov ecx,512/4
rep movsd
mov dx,vesa_info.VbeVersion
mov vesa_ver,dx
mov dx,vesa_info.TotalMemory
mov Total64Kblocks,dx
xor edx,edx
mov dx,wptr [vesa_info.VideoModePtr + 2]
xor ebx,ebx
mov bx,wptr [vesa_info.VideoModePtr]
.if dx==_8kbufferseg ;some VESA BIOS return the list right in the vesa_info block
mov edx,offset vesa_info
add edx,ebx
.else
shl edx,4
add edx,ebx ; EDX points to video mode list.
.endif
mov vesa_list,edx
popad
xor eax,eax
mov ax,vesa_ver
ret
bad: ;Vesa not detected
popad
mov eax,ERROR
ret
vesa_init endp
getinfo proc private,mode:word
mov ax,_8kbufferseg
mov _es_,ax
mov ax,4F01h
mov cx,mode
and cx,01ffh ; read bits 0..8
xor edi,edi ; ES:DI -> 256 byte buffer
int 10h
cmp ax,004Fh
.if !zero?
mov eax,ERROR
ret
.endif
mov esi,_8kbuffer
mov edi,offset vesa_modeinfo
mov ecx,256/4
rep movsd
xor eax,eax
ret
getinfo endp
vesa_getmode PROC private,x:word,y:word,bpp:byte
local using_std:byte
.if !vesa_list
mov eax,ERROR
ret
.endif
pushad
;
; Search video mode list for the required mode.
; The vesa driver Func 4F00h fills in the buffer with the information.
; Offset 0Eh of this buffer contains a real mode SEG:OFS of the video
; mode list. This list consists of each supported VESA mode and
; terminates with 0FFFFh.
;
; Get the real mode far pointer of the video mode list and
; convert the real mode SEG:OFS address into a 32bit near pointer.
mov using_std,0
mov edx,vesa_list
xor eax,eax
@@:
mov ax,[edx] ; Read video mode from list
cmp ax,0FFFFh
.if zero?
.if using_std
jmp bad
.endif
inc using_std ;set using_std
mov edx,offset std_list
jmp @b
.endif
push edx
callp getinfo,ax ;does not preserve regs
pop edx
mov ax,vesa_modeinfo.WinSize
cmp ax,64
jnz try_next ;require 64K window sizes (this should never be a problem)
mov ax,vesa_modeinfo.ModeAttributes
test ax,1
jz try_next ;hardware does not support this mode
mov al,vesa_modeinfo.WinAAttributes
and al,0110b
cmp al,0110b
jnz try_next ;mode not supported or not usable
mov ax,vesa_modeinfo.XResolution
.if ax!=x
jmp try_next
.endif
mov ax,vesa_modeinfo.YResolution
.if ax!=y
jmp try_next
.endif
mov al,vesa_modeinfo.BitsPerPixel
.if al!=bpp
jmp try_next
.endif
;current mode is acceptable
mov ax,[edx]
mov vesamode,ax
jmp @f
try_next:
add edx,2
jmp @b
bad:
popad
mov eax,ERROR
ret
@@:
;setup X/Y/BPP values
;Get bytes per scan line for the protected mode SetStart function.
;this is also used by v_copy
xor eax,eax
mov ax,vesa_modeinfo.BytesPerScanLine
mov getmode_bpsl,ax
popad
mov eax,1 ;linear mode
Test vesa_modeinfo.ModeAttributes ,10000000b ;linear avail?
.if zero?
mov eax,0 ;banking mode
.endif
ret
vesa_getmode endp
vesa_setmode proc private
; Set VIDEO mode
.if !vesamode
mov eax,ERROR
ret
.endif
pushad
; ******************************************************
; Setup for linear memory mapping mode.
; ******************************************************
Test vesa_modeinfo.ModeAttributes ,10000000b ;linear avail?
jz DoWithBanks
;
; Calulate a near pointer to physical linear mapping address.
;
add vesamode,4000h
Mov ebx,vesa_modeinfo.PhysBasePtr
mov cx,bx
shr ebx,16
mov si,Total64Kblocks
xor edi,edi
mov ax,0800h ; map physical memory
int 31h
jc bad
shl ebx,16
mov bx,cx
mov eax,ebx ; eax = linear address
@@:
mov _800_,eax
mov _v_linear,eax
jmp Finished
DoWithBanks:
; ******************************************************
; Setup for windowing mode.
; ******************************************************
; check is windowing is avalible ( writable and readable )
Test vesa_modeinfo.ModeAttributes ,01000000b ;available?
jnz bad
;
; Setup Bank Shift number (I got idea from Dr. Dobbs)
;
Movzx ebx,vesa_modeinfo.WinGranularity
xor edx,edx ;bankshift
mov ecx,64
.while (ecx != ebx)
inc edx
shr ecx,1
.endw
mov bankshift,dl ;used in vesa_setbank proc
;
; Calulate 32bit linear pointer to CPU video memory WindowA
;
Movzx eax,vesa_modeinfo.WinASegment
shl eax,4
mov _v_linear,eax
Finished:
;
; If 32bit VBE inteface is availible then use it
;
mov ax,4f0ah
mov bl,0 ; return pmode interface
int 10h
cmp ax,004fh
jne No32bitInterface
xor esi,esi
mov si,_es_ ; convert ES:DI to 32bit near ptr
shl esi,4
movzx edi,di
add esi,edi
; Use protected mode bank proc only for zero length memory list.
movzx edi,word ptr [ESI+06] ; get port/memory table list
and edi,edi
jz @@usePmodeBanks
@@:
cmp word Ptr [ESI+EDI],0FFFFh ; search port list
lea edi,[edi+2]
jne @b
cmp Word Ptr [ESI+EDI],0FFFFh ; see if mem list is zero
jne @@SkipPmodeBanks
@@usePmodeBanks:
movzx eax,Word Ptr [ESI+00]
add eax,esi
mov [vbesetbank],eax ; save Set Bank code address.
@@SkipPmodeBanks:
; Save Set display start code address.
movzx eax,Word Ptr [ESI+02]
add eax,esi
mov [PmodeSetStart],eax
mov [vesa_setstart_proc],Offset SetStart_ProtectedMode
; adjust for plane boundary for 8 bit+ modes
mov [VBE_StarPerPixelFactor],0
Cmp [vesa_modeinfo.BitsPerPixel],4
je @f
mov [VBE_StarPerPixelFactor],2
@@:
jmp @f
No32bitInterface:
mov vbesetbank,Offset SetBank_RealMode
mov vesa_setstart_proc,Offset SetStart_RealMode
@@:
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
mov bx,vesamode
mov ax,4f02h
int 10h
mov exitmode,offset vesa_uninit
popad ;EAX will be poped off
xor eax,eax
ret
bad:
popad
mov eax,ERROR
ret
vesa_setmode ENDP
vesa_firstmode proc
mov eax,vesa_list
.if !eax
mov eax,ERROR
ret
.endif
pushad
mov edx,eax
@@:
mov ax,[edx]
.if ax==0ffffh
mov vesa_list_pos,edx
popad
mov eax,ERROR
ret
.endif
push edx
callp getinfo,ax
pop edx
mov ax,vesa_modeinfo.WinSize
cmp ax,64
jnz bad ;require 64K window sizes (this should never be a problem)
mov al,vesa_modeinfo.WinAAttributes
and al,0110b ;mode read/write able?
cmp al,0110b
jnz bad
mov ax,vesa_modeinfo.ModeAttributes
test ax,1
jz bad ;mode not supported or not usable
mov vesa_list_pos,edx
popad
xor eax,eax
ret
bad:
add edx,2
jmp @b
vesa_firstmode endp
vesa_nextmode proc
pushad
mov edx,vesa_list_pos
.if !edx
popad
mov eax,ERROR
ret
.endif
mov ax,[edx]
.if ax==0ffffh
jmp bad
.endif
add edx,2 ;next
@@:
mov ax,[edx]
.if ax==0ffffh
mov vesa_list_pos,edx
bad:
popad
mov eax,ERROR
ret
.endif
push edx
callp getinfo,ax
pop edx
mov ax,vesa_modeinfo.WinSize
cmp ax,64
jnz bad ;require 64K window sizes (this should never be a problem)
mov al,vesa_modeinfo.WinAAttributes
and al,0110b ;mode read/write able?
cmp al,0110b
jnz next
mov ax,vesa_modeinfo.ModeAttributes
test ax,1
jz next ;mode not supported or not usable
mov vesa_list_pos,edx
popad
xor eax,eax
ret
next:
add edx,2
jmp @b
vesa_nextmode endp
;Alway consider each back to be 64K and will never overlay
;(regardless of current hardware)
;this driver will simulate the non-overlaping 64K banks
vesa_setbank PROC private,banknum:byte
mov al,banknum
cmp vesa_current_bank,al
jz @f
pushad
mov dl,al
and edx,01fh
mov vesa_current_bank,dl
mov cl,bankshift
shl edx,cl
xor ebx,ebx
call [vbesetbank]
popad
@@:
xor eax,eax
ret
vesa_setbank ENDP
vesa_nextbank PROC private
pushad
xor edx,edx
mov dl,vesa_current_bank
inc dl
mov vesa_current_bank,dl
mov cl,bankshift
shl edx,cl
xor ebx,ebx
call [vbesetbank]
popad
xor eax,eax
ret
vesa_nextbank ENDP
; VBE Function 06h - Set/Get Logical Scan Line Length
; You must call this when using Func #6 (the driver needs the BX returned from VESA)
vesa_func06 PROC
mov ax,4F06h
int 10h
cmp ah,00h
jne @f
mov wptr[_v_bpsl],bx
@@:
ret
vesa_func06 ENDP
;***********************************************************
; Call real mode set video bank function
; Note: very very slow....
;***********************************************************
SetBank_RealMode PROC private
push ebx
xor ebx,ebx
mov ax,04F05h
int 10h
pop ebx
Ret
SetBank_RealMode ENDP
;--------------------------------------------------------
; Call real mode set display start bank function
; CX=pixel in scan line
; DX=scan line number
; Note: very very slow....
;----------------------------------------------------------
SetStart_RealMode PROC private
push ebx
xor ebx,ebx
mov ax,04F07h
int 10h
pop ebx
Ret
SetStart_RealMode ENDP
;--------------------------------------------------------
; Call Protected mode set display start bank function
; ECX=pixel in scan line
; EDX=scan line number
;----------------------------------------------------------
SetStart_ProtectedMode PROC private
push ebx
xor ebx,ebx
imul edx,[_v_bpsl]
add edx,ecx
mov cl,[VBE_StarPerPixelFactor]
shr edx,cl
mov cx,dx
shr edx,16
mov ax,04F07h
Call [PmodeSetStart]
pop ebx
Ret
SetStart_ProtectedMode ENDP
vesa_setstart proc,start:dword,scan:dword
pushad
mov ecx,start
mov edx,scan
call vesa_setstart_proc
popad
ret
vesa_setstart endp